diff: Add ostree_diff_dirs_with_options(), expose via cmdline
authorErik Larsson <erik@ortogonal.com>
Wed, 8 Feb 2017 20:59:38 +0000 (21:59 +0100)
committerAtomic Bot <atomic-devel@projectatomic.io>
Tue, 21 Mar 2017 13:38:04 +0000 (13:38 +0000)
The first options are owner_uid/owner_gid, which makes it possible to use diff
on local files where --owner-uid/gid have been passed to commit.

Closes: #740
Approved by: cgwalters

apidoc/ostree-sections.txt
man/ostree-diff.xml
src/libostree/libostree.sym
src/libostree/ostree-diff.c
src/libostree/ostree-diff.h
src/ostree/ot-builtin-diff.c
tests/basic-test.sh

index cba6ec467e78323cc5db97006932f002b4729dcd..027f25c5c0efbb7b6dbd5babc3ea87ea067a422e 100644 (file)
@@ -172,6 +172,7 @@ OstreeDiffItem
 ostree_diff_item_ref
 ostree_diff_item_unref
 ostree_diff_dirs
+ostree_diff_dirs_with_options
 ostree_diff_print
 <SUBSECTION Standard>
 ostree_diff_item_get_type
index aaa76b13729def974e4ea2c64ac4f4d59cd00a76..906374b4abfbeee35e1c09f61936f5cc4d7d8b22 100644 (file)
@@ -78,6 +78,20 @@ Boston, MA 02111-1307, USA.
                     Print filesystem diff.
                 </para></listitem>
             </varlistentry>
+
+            <varlistentry>
+                <term><option>--owner-uid</option></term>
+                <listitem><para>
+                    Use file ownership user id for local files.
+                </para></listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term><option>--owner-gid</option></term>
+                <listitem><para>
+                    Use file ownership group id for local files.
+                </para></listitem>
+            </varlistentry>
         </variablelist>
     </refsect1>
 
index 9067a26c3d4f654d98cce7eff4743e6fe54b3dd5..649c6f1fc789924acc9fdb8a90034530730a0984 100644 (file)
@@ -389,6 +389,7 @@ global:
 LIBOSTREE_2017.4 {
 global:
   ostree_check_version;
+  ostree_diff_dirs_with_options;
 } LIBOSTREE_2017.3;
 
 /* Stub section for the stable release *after* this development one; don't
index 69a67b7600c65ef42eff2ed909fa2d608e644c6d..5537ee874b71c77fc00419615ea7a54ef52cd8bc 100644 (file)
@@ -225,6 +225,37 @@ ostree_diff_dirs (OstreeDiffFlags flags,
                   GPtrArray      *added,
                   GCancellable   *cancellable,
                   GError        **error)
+{
+  return ostree_diff_dirs_with_options (flags, a, b, modified,
+                                        removed, added, NULL,
+                                        cancellable, error);
+}
+
+/**
+ * ostree_diff_dirs_with_options:
+ * @flags: Flags
+ * @a: First directory path, or %NULL
+ * @b: First directory path
+ * @modified: (element-type OstreeDiffItem): Modified files
+ * @removed: (element-type Gio.File): Removed files
+ * @added: (element-type Gio.File): Added files
+ * @cancellable: Cancellable
+ * @options: (allow-none): Options
+ * @error: Error
+ *
+ * Compute the difference between directory @a and @b as 3 separate
+ * sets of #OstreeDiffItem in @modified, @removed, and @added.
+ */
+gboolean
+ostree_diff_dirs_with_options (OstreeDiffFlags        flags,
+                               GFile                 *a,
+                               GFile                 *b,
+                               GPtrArray             *modified,
+                               GPtrArray             *removed,
+                               GPtrArray             *added,
+                               OstreeDiffDirsOptions *options,
+                               GCancellable          *cancellable,
+                               GError               **error)
 {
   gboolean ret = FALSE;
   GError *temp_error = NULL;
@@ -233,6 +264,10 @@ ostree_diff_dirs (OstreeDiffFlags flags,
   g_autoptr(GFile) child_b = NULL;
   g_autoptr(GFileInfo) child_a_info = NULL;
   g_autoptr(GFileInfo) child_b_info = NULL;
+  OstreeDiffDirsOptions default_opts = OSTREE_DIFF_DIRS_OPTIONS_INIT;
+
+  if (!options)
+    options = &default_opts;
 
   if (a == NULL)
     {
@@ -316,6 +351,11 @@ ostree_diff_dirs (OstreeDiffFlags flags,
         }
       else
         {
+          if (options->owner_uid >= 0)
+            g_file_info_set_attribute_uint32 (child_b_info, "unix::uid", options->owner_uid);
+          if (options->owner_gid >= 0)
+            g_file_info_set_attribute_uint32 (child_b_info, "unix::gid", options->owner_gid);
+
           child_b_type = g_file_info_get_file_type (child_b_info);
           if (child_a_type != child_b_type)
             {
@@ -337,8 +377,9 @@ ostree_diff_dirs (OstreeDiffFlags flags,
 
               if (child_a_type == G_FILE_TYPE_DIRECTORY)
                 {
-                  if (!ostree_diff_dirs (flags, child_a, child_b, modified,
-                                         removed, added, cancellable, error))
+                  if (!ostree_diff_dirs_with_options (flags, child_a, child_b, modified,
+                                                      removed, added, options,
+                                                      cancellable, error))
                     goto out;
                 }
             }
index 781bf7681dc2bd63d70a85a850a8d5c6a6ae8a58..b33bd63a668d7ffe883d81c6bdefd3d741e471e9 100644 (file)
@@ -71,6 +71,42 @@ gboolean ostree_diff_dirs (OstreeDiffFlags flags,
                            GCancellable   *cancellable,
                            GError        **error);
 
+/**
+ * OstreeDiffDirsOptions:
+ *
+ * An extensible options structure controlling diff dirs. Make sure
+ * that owner_uid/gid is set to -1 when not used. This is used by
+ * ostree_diff_dirs_with_options().
+ */
+typedef struct {
+  gint owner_uid;
+  gint owner_gid;
+
+  OstreeRepoDevInoCache *devino_to_csum_cache;
+
+  gboolean unused_bools[7];
+  int unused_ints[6];
+  gpointer unused_ptrs[7];
+} OstreeDiffDirsOptions;
+
+/**
+ * OSTREE_DIFF_DIRS_OPTIONS_INIT:
+ *
+ * Use this to initialize an `OstreeDiffDirsOptions` structure.
+ */
+#define OSTREE_DIFF_DIRS_OPTIONS_INIT { .owner_uid = -1, .owner_gid = -1, }
+
+_OSTREE_PUBLIC
+gboolean ostree_diff_dirs_with_options (OstreeDiffFlags       flags,
+                                        GFile                 *a,
+                                        GFile                 *b,
+                                        GPtrArray             *modified,
+                                        GPtrArray             *removed,
+                                        GPtrArray             *added,
+                                        OstreeDiffDirsOptions *options,
+                                        GCancellable          *cancellable,
+                                        GError                **error);
+
 _OSTREE_PUBLIC
 void ostree_diff_print (GFile          *a,
                         GFile          *b,
index 963a8b7ccf1e5c60e949ef0627301df2c8815469..a7e2aad2917d0aca95103cfd69ca31c4c6a09ee3 100644 (file)
 static gboolean opt_stats;
 static gboolean opt_fs_diff;
 static gboolean opt_no_xattrs;
+static gint opt_owner_uid = -1;
+static gint opt_owner_gid = -1;
 
 static GOptionEntry options[] = {
   { "stats", 0, 0, G_OPTION_ARG_NONE, &opt_stats, "Print various statistics", NULL },
   { "fs-diff", 0, 0, G_OPTION_ARG_NONE, &opt_fs_diff, "Print filesystem diff", NULL },
   { "no-xattrs", 0, 0, G_OPTION_ARG_NONE, &opt_no_xattrs, "Skip output of extended attributes", NULL },
+  { "owner-uid", 0, 0, G_OPTION_ARG_INT, &opt_owner_uid, "Use file ownership user id for local files", "UID" },
+  { "owner-gid", 0, 0, G_OPTION_ARG_INT, &opt_owner_gid, "Use file ownership group id for local files", "GID" },
   { NULL }
 };
 
@@ -177,8 +181,10 @@ ostree_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **
       modified = g_ptr_array_new_with_free_func ((GDestroyNotify)ostree_diff_item_unref);
       removed = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
       added = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
-      
-      if (!ostree_diff_dirs (diff_flags, srcf, targetf, modified, removed, added, cancellable, error))
+
+      OstreeDiffDirsOptions diff_opts = { opt_owner_uid, opt_owner_gid };
+      if (!ostree_diff_dirs_with_options (diff_flags, srcf, targetf, modified, removed,
+                                          added, &diff_opts, cancellable, error))
         goto out;
 
       ostree_diff_print (srcf, targetf, modified, removed, added);
index 045e4217bf9fad325d0433943f1883625079c764..68c7b0a650a5c0ce566a580354592890e44fdce0 100644 (file)
@@ -19,7 +19,7 @@
 
 set -euo pipefail
 
-echo "1..63"
+echo "1..65"
 
 $CMD_PREFIX ostree --version > version.yaml
 python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
@@ -171,6 +171,21 @@ cd ${test_tmpdir}
 assert_file_has_content diff-test2-2 'A *oh-look-a-file$'
 echo "ok diff cwd"
 
+cd ${test_tmpdir}/checkout-test2-4
+$OSTREE diff test2 ./ > ${test_tmpdir}/diff-test2
+assert_file_empty ${test_tmpdir}/diff-test2
+$OSTREE diff test2 --owner-uid=$((`id -u`+1)) ./ > ${test_tmpdir}/diff-test2
+assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet$'
+assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet/message$'
+assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet/another/tree/green$'
+echo "ok diff file with different uid"
+
+$OSTREE diff test2 --owner-gid=$((`id -g`+1)) ./ > ${test_tmpdir}/diff-test2
+assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet$'
+assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet/message$'
+assert_file_has_content ${test_tmpdir}/diff-test2 'M */yet/another/tree/green$'
+echo "ok diff file with different gid"
+
 cd ${test_tmpdir}/checkout-test2-4
 rm four
 mkdir four